package me.xlgp.xiquzimu.data;

import java.util.List;

import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Flowable;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.functions.Function;
import me.xlgp.xiquzimu.dao.ChangDuanDao;
import me.xlgp.xiquzimu.db.AppDatabase;
import me.xlgp.xiquzimu.designpatterns.ObserverHelper;
import me.xlgp.xiquzimu.model.ChangCi;
import me.xlgp.xiquzimu.model.ChangDuan;
import me.xlgp.xiquzimu.model.ChangDuanInfo;
import me.xlgp.xiquzimu.util.ChangDuanHelper;

public class ChangDuanRepository {

    public Flowable<List<ChangDuan>> list() {
        ChangDuanDao changDuanDao = AppDatabase.getInstance().changDuanDao();
        return changDuanDao.flowableList().compose(ObserverHelper.flowableTransformer());
    }

    public Flowable<List<ChangDuan>> list(String juZhong) {
        ChangDuanDao changDuanDao = AppDatabase.getInstance().changDuanDao();
        return changDuanDao.flowableList(juZhong).compose(ObserverHelper.flowableTransformer());
    }

    public long save(ChangDuanInfo ziMuInfo) {
        AppDatabase db = AppDatabase.getInstance();
        long id = db.changDuanDao().insert(ziMuInfo.getChangDuan());
        List<ChangCi> changCiList = ziMuInfo.getChangCiList();
        for (int i = 0; i < changCiList.size(); i++) {
            changCiList.get(i).setChangDuanId(id);
        }
        db.changCiDao().insert(changCiList);
        return id;
    }

    public @NonNull Observable<Long> saveAynsc(ChangDuanInfo ziMuInfo) {
        return Observable.just(ziMuInfo)
                .filter(changDuanInfo12 -> changDuanInfo12.getChangDuan() != null && changDuanInfo12.getChangCiList().size() > 0).map(this::save).compose(ObserverHelper.transformer());
    }

    //从远程更新单个唱段
    public @NonNull Observable<Long> update(String name) {
        return new FetchRemoteRepository().changDuan(name)
                .flatMap((Function<List<String>, ObservableSource<Long>>) list -> {
                    ChangDuanInfo changDuanInfo = ChangDuanHelper.parse(list);
                    new JuZhongRepository().save(changDuanInfo.getChangDuan().getJuZhong());
                    return saveAynsc(changDuanInfo);
                })
                .compose(ObserverHelper.transformer());
    }

    //本地更新单个唱段
    public @NonNull Observable<Object> update(ChangDuanInfo ziMuInfo) {
        return Observable.create(emitter -> {
            try {
                AppDatabase db = AppDatabase.getInstance();
                db.changDuanDao().insert(ziMuInfo.getChangDuan());
                ziMuInfo.getChangCiList().forEach(changCi -> {
                    if (changCi.getId() == null) {
                        changCi.setChangDuanId(ziMuInfo.getChangDuan().getId());
                    }
                });
                db.changCiDao().insert(ziMuInfo.getChangCiList());
                emitter.onComplete();
            } catch (Exception e) {
                emitter.onError(e);
            }
        }).compose(ObserverHelper.transformer());
    }

    public Observable<me.xlgp.xiquzimu.responsebody.ChangDuanInfo> getNameList() {
        return new FetchRemoteRepository().getChangDuanInfo();
    }

    public ChangDuan get(Integer id) {
        ChangDuanDao changDuanDao = AppDatabase.getInstance().changDuanDao();
        return changDuanDao.get(id);
    }

    public @NonNull Observable<Object> delete(ChangDuan data) {
        return Observable.create(emitter -> {
            AppDatabase db = AppDatabase.getInstance();
            db.changDuanDao().delete(data);
            db.changCiDao().deleteByChangDuanId(data.getId());
            emitter.onNext(true);
        }).compose(ObserverHelper.transformer());
    }

    public void deleteAll() {
        ChangDuanDao changDuanDao = AppDatabase.getInstance().changDuanDao();
        changDuanDao.deleteAll();
    }

    public int deleteList(List<Integer> idList) {
        ChangDuanDao changDuanDao = AppDatabase.getInstance().changDuanDao();
        return changDuanDao.deleteByIdList(idList);
    }
}
